using System;
using System.Collections.Generic;
using System.Text;

namespace RapidHDL
{
    public class TestPipeLineBuffer : RapidHardware
    {
        PipelineStage oPipe1;
        PipelineStage oPipe2;
        PipelineStage oPipe3;
        PipelineBuffer oBuffer;

        public override bool ConfigureSettings()
        {
            Settings.UseStart = false;
            Settings.BuildHardware = true;
            Settings.ForceBuildHardware = false;
            Settings.RunFromXilinx = true;
            Settings.ClockFrequency = 10;
            Settings.UseSDRAM = true;
            Settings.BuildRemote = true;
            return true;
        }

        public override bool GenerateStructure(TopLevelComponent TopLevelComponent)
        {

            oBuffer = new PipelineBuffer(TopLevelComponent, "buffer", TopLevelComponent.MainClock, TopLevelComponent.MainReset, 5, 3);

            oPipe1 = oBuffer.Stages[0];
            oPipe2 = oBuffer.Stages[1];
            oPipe3 = oBuffer.Stages[2];

            SystemInterface.AddSignalSource("stall_i", oBuffer.OutputBus.Stall, 0);
            SystemInterface.AddSignalSource("data_i", oBuffer.InputBus.Data, 0);
            SystemInterface.AddSignalSource("data_ready_i", oBuffer.InputBus.DataReady, 0);

            TopLevelComponent.TestBusWrite.Join(0);
           
            return true;
        }

        public override bool ConfigureSignalViews(TopLevelComponent TopLevelComponent)
        {
            SystemInterface.AddSignalView("pipe1_ready_o", oPipe1.OutputBus.DataReady);
            SystemInterface.AddSignalView("pipe2_ready_o", oPipe2.OutputBus.DataReady);
            SystemInterface.AddSignalView("pipe3_ready_o", oPipe3.OutputBus.DataReady);

            SystemInterface.AddSignalView("pipe1_o", oPipe1.OutputBus.Data);
            SystemInterface.FormatSignalView("pipe1_o", SignalFormat.Unsigned);
            SystemInterface.AddSignalView("pipe2_o", oPipe2.OutputBus.Data);
            SystemInterface.FormatSignalView("pipe2_o", SignalFormat.Unsigned);
            SystemInterface.AddSignalView("pipe3_o", oPipe3.OutputBus.Data);
            SystemInterface.FormatSignalView("pipe3_o", SignalFormat.Unsigned);

            SystemInterface.AddSignalView("stall_o", oBuffer.InputBus.Stall);
            SystemInterface.AddSignalView("data_o", oBuffer.OutputBus.Data);
            SystemInterface.AddSignalView("data_ready_o", oBuffer.OutputBus.DataReady);

            return true;
        }


        private void ShowOutputs(HardwareScript poScript, int piTime)
        {
            poScript.SignalView(piTime, "pipe1_o");
            poScript.SignalView(piTime, "pipe1_ready_o");
            poScript.SignalView(piTime, "pipe2_o");
            poScript.SignalView(piTime, "pipe2_ready_o");
            poScript.SignalView(piTime, "pipe3_o");
            poScript.SignalView(piTime, "pipe3_ready_o");
            poScript.Echo(piTime, "*******************");
            poScript.SignalView(piTime, "stall_o");
            poScript.SignalView(piTime, "data_o");
            poScript.SignalView(piTime, "data_ready_o");
            poScript.Echo(piTime, "----");
        }

        private void SetInputs(HardwareScript poScript, int piTime, int piStall, int piData, int piDataReady)
        {
            poScript.SignalOut(piTime, "stall_i", piStall.ToString());
            poScript.SignalOut(piTime, "data_ready_i", piDataReady.ToString());
            poScript.SignalOut(piTime, "data_i", piData.ToString(), SignalFormat.Unsigned);
            //poScript.Pause(piTime+1);
        }

        public override bool GenerateHardwareScripts()
        {
            HardwareScript oScript = HardwareScripts.NewScript("test");
            SetInputs(oScript, 0, 0, 0, 0);

            ShowOutputs(oScript, 1);

            SetInputs(oScript, 2, 0, 2, 1);
            ShowOutputs(oScript, 2);
            SetInputs(oScript, 3, 0, 3, 1);
            ShowOutputs(oScript, 3);

            SetInputs(oScript, 4, 0, 4, 1);
            ShowOutputs(oScript, 4);

            SetInputs(oScript, 5, 1, 5, 1);
            ShowOutputs(oScript, 5);

            SetInputs(oScript, 6, 1, 6, 1);
            ShowOutputs(oScript, 6);
            oScript.Pause(6);

            SetInputs(oScript, 7, 1, 7, 1);
            ShowOutputs(oScript, 7);

            SetInputs(oScript, 8, 0, 8, 1);
            ShowOutputs(oScript, 8);

            SetInputs(oScript, 9, 0, 9, 0);
            ShowOutputs(oScript, 9);

            SetInputs(oScript, 10, 0, 10, 0);
            ShowOutputs(oScript, 10);

            SetInputs(oScript, 11, 0, 11, 1);
            ShowOutputs(oScript, 11);

            SetInputs(oScript, 12, 0, 12, 0);
            ShowOutputs(oScript, 12);
            ShowOutputs(oScript, 13);
            ShowOutputs(oScript, 14);
            ShowOutputs(oScript, 15);

            return true;
        }


    }
}


